import { RoomType, RoomStatus } from '../../../types/room';
import type { Room, RoomAvailability } from '../../../types/room';

// 多维索引接口
interface MultiDimensionalIndex {
  // 主索引：roomId -> monthIndex -> RoomAvailability
  primaryIndex: Map<string, Map<number, RoomAvailability>>;

  // 状态索引：status -> Set<roomId>
  statusIndex: Map<RoomStatus, Set<string>>;

  // 房型索引：roomType -> Set<roomId>
  roomTypeIndex: Map<RoomType, Set<string>>;

  // 建筑索引：building -> Set<roomId>
  buildingIndex: Map<string, Set<string>>;

  // 月份索引：monthIndex -> Set<roomId>
  monthIndex: Map<number, Set<string>>;

  // 反向索引：快速查找
  roomIdToRoom: Map<string, Room>;

  // 缓存统计
  cacheStats: {
    hitCount: number;
    missCount: number;
    rebuildCount: number;
  };
}

// 月份字符串到数字的映射
const MONTH_TO_INDEX: Record<string, number> = {
  '2025/1月': 0,
  '2025/2月': 1,
  '2025/3月': 2,
  '2025/4月': 3,
  '2025/5月': 4,
  '2025/6月': 5,
  '2025/7月': 6,
};

const INDEX_TO_MONTH: Record<number, string> = {
  0: '2025/1月',
  1: '2025/2月',
  2: '2025/3月',
  3: '2025/4月',
  4: '2025/5月',
  5: '2025/6月',
  6: '2025/7月',
};

export class DataIndexManager {
  private index: MultiDimensionalIndex;
  private lastRoomsHash: string = '';
  private lastAvailabilitiesHash: string = '';

  constructor() {
    this.index = {
      primaryIndex: new Map(),
      statusIndex: new Map(),
      roomTypeIndex: new Map(),
      buildingIndex: new Map(),
      monthIndex: new Map(),
      roomIdToRoom: new Map(),
      cacheStats: {
        hitCount: 0,
        missCount: 0,
        rebuildCount: 0,
      },
    };
  }

  // 构建索引
  buildIndex(rooms: Room[], availabilities: RoomAvailability[]): void {
    const roomsHash = this.hashArray(rooms);
    const availabilitiesHash = this.hashArray(availabilities);

    // 检查是否需要重建索引
    if (
      roomsHash === this.lastRoomsHash &&
      availabilitiesHash === this.lastAvailabilitiesHash
    ) {
      this.index.cacheStats.hitCount++;
      return;
    }

    console.time('DataIndex Build');

    // 清空现有索引
    this.clearIndex();

    // 构建房间索引
    this.buildRoomIndex(rooms);

    // 构建可用性索引
    this.buildAvailabilityIndex(availabilities);

    // 更新哈希值
    this.lastRoomsHash = roomsHash;
    this.lastAvailabilitiesHash = availabilitiesHash;
    this.index.cacheStats.rebuildCount++;

    console.timeEnd('DataIndex Build');
    console.log('索引构建完成，统计:', this.getStats());
  }

  // 构建房间索引
  private buildRoomIndex(rooms: Room[]): void {
    for (const room of rooms) {
      // 房间ID到房间对象映射
      this.index.roomIdToRoom.set(room.id, room);

      // 房型索引
      if (!this.index.roomTypeIndex.has(room.roomType)) {
        this.index.roomTypeIndex.set(room.roomType, new Set());
      }
      this.index.roomTypeIndex.get(room.roomType)!.add(room.id);

      // 建筑索引
      if (!this.index.buildingIndex.has(room.building)) {
        this.index.buildingIndex.set(room.building, new Set());
      }
      this.index.buildingIndex.get(room.building)!.add(room.id);
    }
  }

  // 构建可用性索引
  private buildAvailabilityIndex(availabilities: RoomAvailability[]): void {
    for (const availability of availabilities) {
      const { roomId, month, status } = availability;
      const monthIndex = MONTH_TO_INDEX[month];

      if (monthIndex === undefined) {
        console.warn(`未知月份: ${month}`);
        continue;
      }

      // 主索引
      if (!this.index.primaryIndex.has(roomId)) {
        this.index.primaryIndex.set(roomId, new Map());
      }
      this.index.primaryIndex.get(roomId)!.set(monthIndex, availability);

      // 状态索引
      if (!this.index.statusIndex.has(status)) {
        this.index.statusIndex.set(status, new Set());
      }
      this.index.statusIndex.get(status)!.add(roomId);

      // 月份索引
      if (!this.index.monthIndex.has(monthIndex)) {
        this.index.monthIndex.set(monthIndex, new Set());
      }
      this.index.monthIndex.get(monthIndex)!.add(roomId);
    }
  }

  // 快速查找房间可用性 O(1)
  getRoomAvailability(
    roomId: string,
    month: string
  ): RoomAvailability | undefined {
    const monthIndex = MONTH_TO_INDEX[month];
    if (monthIndex === undefined) return undefined;

    const roomAvailabilities = this.index.primaryIndex.get(roomId);
    if (!roomAvailabilities) return undefined;

    return roomAvailabilities.get(monthIndex);
  }

  // 批量查找房间可用性 O(n)
  getRoomAvailabilities(roomId: string): RoomAvailability[] {
    const roomAvailabilities = this.index.primaryIndex.get(roomId);
    if (!roomAvailabilities) return [];

    return Array.from(roomAvailabilities.values());
  }

  // 按状态查找房间
  getRoomsByStatus(status: RoomStatus): Room[] {
    const roomIds = this.index.statusIndex.get(status);
    if (!roomIds) return [];

    return Array.from(roomIds)
      .map(id => this.index.roomIdToRoom.get(id))
      .filter((room): room is Room => room !== undefined);
  }

  // 按房型查找房间
  getRoomsByType(roomType: RoomType): Room[] {
    const roomIds = this.index.roomTypeIndex.get(roomType);
    if (!roomIds) return [];

    return Array.from(roomIds)
      .map(id => this.index.roomIdToRoom.get(id))
      .filter((room): room is Room => room !== undefined);
  }

  // 按建筑查找房间
  getRoomsByBuilding(building: string): Room[] {
    const roomIds = this.index.buildingIndex.get(building);
    if (!roomIds) return [];

    return Array.from(roomIds)
      .map(id => this.index.roomIdToRoom.get(id))
      .filter((room): room is Room => room !== undefined);
  }

  // 按月份查找有预订的房间
  getRoomsWithBookingInMonth(month: string): Room[] {
    const monthIndex = MONTH_TO_INDEX[month];
    if (monthIndex === undefined) return [];

    const roomIds = this.index.monthIndex.get(monthIndex);
    if (!roomIds) return [];

    return Array.from(roomIds)
      .map(id => this.index.roomIdToRoom.get(id))
      .filter((room): room is Room => room !== undefined);
  }

  // 复合查询：按房型和状态查找
  getRoomsByTypeAndStatus(roomType: RoomType, status: RoomStatus): Room[] {
    const typeRoomIds = this.index.roomTypeIndex.get(roomType);
    const statusRoomIds = this.index.statusIndex.get(status);

    if (!typeRoomIds || !statusRoomIds) return [];

    // 计算交集
    const intersection = new Set(
      Array.from(typeRoomIds).filter(id => statusRoomIds.has(id))
    );

    return Array.from(intersection)
      .map(id => this.index.roomIdToRoom.get(id))
      .filter((room): room is Room => room !== undefined);
  }

  // 范围查询：获取某段时间内的所有预订
  getAvailabilitiesInRange(
    startMonth: string,
    endMonth: string
  ): RoomAvailability[] {
    const startIndex = MONTH_TO_INDEX[startMonth];
    const endIndex = MONTH_TO_INDEX[endMonth];

    if (startIndex === undefined || endIndex === undefined) return [];

    const results: RoomAvailability[] = [];

    for (let monthIndex = startIndex; monthIndex <= endIndex; monthIndex++) {
      const roomIds = this.index.monthIndex.get(monthIndex);
      if (roomIds) {
        for (const roomId of roomIds) {
          const availability = this.index.primaryIndex
            .get(roomId)
            ?.get(monthIndex);
          if (availability) {
            results.push(availability);
          }
        }
      }
    }

    return results;
  }

  // 聚合查询：统计信息
  getStatistics() {
    const stats = {
      totalRooms: this.index.roomIdToRoom.size,
      totalAvailabilities: 0,
      statusDistribution: {} as Record<RoomStatus, number>,
      typeDistribution: {} as Record<RoomType, number>,
      buildingDistribution: {} as Record<string, number>,
      monthlyBookings: {} as Record<string, number>,
    };

    // 计算总可用性记录数
    for (const roomAvailabilities of this.index.primaryIndex.values()) {
      stats.totalAvailabilities += roomAvailabilities.size;
    }

    // 统计状态分布
    for (const [status, roomIds] of this.index.statusIndex) {
      stats.statusDistribution[status] = roomIds.size;
    }

    // 统计房型分布
    for (const [type, roomIds] of this.index.roomTypeIndex) {
      stats.typeDistribution[type] = roomIds.size;
    }

    // 统计建筑分布
    for (const [building, roomIds] of this.index.buildingIndex) {
      stats.buildingDistribution[building] = roomIds.size;
    }

    // 统计月份预订
    for (const [monthIndex, roomIds] of this.index.monthIndex) {
      const month = INDEX_TO_MONTH[monthIndex];
      if (month) {
        stats.monthlyBookings[month] = roomIds.size;
      }
    }

    return stats;
  }

  // 获取缓存统计
  getStats() {
    return {
      ...this.index.cacheStats,
      indexSize: {
        primaryIndex: this.index.primaryIndex.size,
        statusIndex: this.index.statusIndex.size,
        roomTypeIndex: this.index.roomTypeIndex.size,
        buildingIndex: this.index.buildingIndex.size,
        monthIndex: this.index.monthIndex.size,
        roomIdToRoom: this.index.roomIdToRoom.size,
      },
    };
  }

  // 清空索引
  private clearIndex(): void {
    this.index.primaryIndex.clear();
    this.index.statusIndex.clear();
    this.index.roomTypeIndex.clear();
    this.index.buildingIndex.clear();
    this.index.monthIndex.clear();
    this.index.roomIdToRoom.clear();
  }

  // 计算数组哈希值 (简单实现)
  private hashArray(arr: unknown[]): string {
    return JSON.stringify(
      arr.map(item => (typeof item === 'object' ? JSON.stringify(item) : item))
    ).slice(0, 100); // 截取前100个字符作为哈希
  }

  // 内存使用估算
  getMemoryUsage(): { estimated: string; breakdown: Record<string, number> } {
    const breakdown = {
      primaryIndex: this.index.primaryIndex.size * 100, // 估算每个entry 100字节
      statusIndex: this.index.statusIndex.size * 50,
      roomTypeIndex: this.index.roomTypeIndex.size * 50,
      buildingIndex: this.index.buildingIndex.size * 50,
      monthIndex: this.index.monthIndex.size * 50,
      roomIdToRoom: this.index.roomIdToRoom.size * 200, // 房间对象较大
    };

    const total = Object.values(breakdown).reduce((sum, size) => sum + size, 0);

    return {
      estimated: `${(total / 1024).toFixed(2)} KB`,
      breakdown,
    };
  }
}

// 单例实例
export const dataIndexManager = new DataIndexManager();
